/**
 * 静态分析模版
 *
 * Created by nongzhizhong on 2022/08/11.
 */
const chai = require('chai');
chai.use(require('chai-http'));
// eslint-disable-next-line no-unused-vars
const should = chai.should();
const randomstring = require('randomstring');
const Administrator = require('./../../../models/administrator');
const uri = require('./../uri');

module.exports = describe('analyze template and rules', function () {
  const administrator = new Administrator();
  let newUser;
  let ruleSets;
  let rules;
  let templateId;
  let updateBody;

  function getRandomRules(num) {
    if (!rules || !rules.length) {
      return [];
    }
    const chance = num / rules.length;
    let arr = [];
    for (let i = 0; i < rules.length && arr.length < num; i += 1) {
      const gap = num - arr.length;
      const left = rules.length - i;
      if (left <= gap) {
        arr = arr.concat(rules.slice(i));
        break;
      }
      if (Math.random() < chance) {
        arr.push(rules[i]);
      }
    }
    return arr;
  }

  before(async function () {
    await administrator.login();
    newUser = await administrator.createRandomTester();
    ruleSets = await newUser.getRules();
    rules = ruleSets
      .reduce((arr, { levels }) => arr.concat(levels
        .reduce((arr1, { rules: lvlRules }) => arr1.concat(lvlRules), [])), []);
  });
  after(async function () {
    await administrator.removeUsers([newUser.userId]);
  });

  // 每个账号默认有一个模板全部规则集的模板
  it('it should list with 1 default template', function (done) {
    chai.request(uri)
      .get('/static-analyze/templates.json')
      .set('Authorization', `Bearer ${newUser.token.accessToken}`)
      .end((err, res) => {
        res.should.have.status(200);
        const { templates } = res.body;
        templates.should.be.a('array').with.lengthOf(1);
        templates[0].should.have.property('isDefault');
        templates[0].isDefault.should.be.a('boolean').with.assert(true);
        done();
      });
  });
  // 创建一个模板
  it('it should create a template', function (done) {
    const body = {
      name: 'create a template',
      languages: ['c', 'c++'],
      description: 'for unit test create a template',
      ruleIds: getRandomRules(5).map((r) => r.ruleId),
    };
    chai.request(uri)
      .post('/static-analyze/templates.json')
      .set('Authorization', `Bearer ${newUser.token.accessToken}`)
      .send(body)
      .end((err, res) => {
        res.should.have.status(200);
        templateId = res.body._id;
        done();
      });
  });
  // 包含创建的模板和默认的模板应该有两个模板
  it('it should list with length 2', function (done) {
    chai.request(uri)
      .get('/static-analyze/templates.json')
      .set('Authorization', `Bearer ${newUser.token.accessToken}`)
      .end((err, res) => {
        res.should.have.status(200);
        res.body.templates.should.be.a('array').with.lengthOf(2);
        done();
      });
  });
  it('it should conflict when template name already be used', function (done) {
    const body = {
      name: 'create a template',
      languages: ['c', 'c++'],
      description: 'for unit test should fail when template name already be used',
      ruleIds: getRandomRules(5).map((r) => r.ruleId),
    };
    chai.request(uri)
      .post('/static-analyze/templates.json')
      .set('Authorization', `Bearer ${newUser.token.accessToken}`)
      .send(body)
      .end((err, res) => {
        res.should.have.status(409);
        done();
      });
  });
  it('it should update template', function (done) {
    const body = {
      name: 'update template',
      languages: ['c', 'c++'],
      description: 'for unit test update template',
      ruleIds: getRandomRules(5).map((r) => r.ruleId),
    };
    updateBody = body;
    chai.request(uri)
      .put(`/static-analyze/templates/${templateId}.json`)
      .set('Authorization', `Bearer ${newUser.token.accessToken}`)
      .send(body)
      .end((err, res) => {
        res.should.have.status(200);
        done();
      });
  });

  it('it should get temmplate detail after update template', function (done) {
    const body = updateBody;
    chai.request(uri)
      .get(`/static-analyze/templates/${templateId}.json`)
      .set('Authorization', `Bearer ${newUser.token.accessToken}`)
      .end((err, res) => {
        res.should.have.status(200);
        res.body.name.should.be.eql(body.name);
        chai.assert.deepEqual(res.body.languages, body.languages);
        chai.assert.deepEqual(res.body.ruleIds, body.ruleIds);
        done();
      });
  });
  // 删除模板
  it('it should deleted temmplate', function (done) {
    chai.request(uri)
      .delete(`/static-analyze/templates/${templateId}.json`)
      .set('Authorization', `Bearer ${newUser.token.accessToken}`)
      .end((err, res) => {
        res.should.have.status(204);
        done();
      });
  });
  // 获取不存在的模板
  it('it should temmplate is not found by templateId', function (done) {
    chai.request(uri)
      .delete(`/static-analyze/templates/${randomstring.generate({ length: 24, charset: 'hex' })}.json`)
      .set('Authorization', `Bearer ${newUser.token.accessToken}`)
      .end((err, res) => {
        res.should.have.status(404);
        done();
      });
  });
});
